package com.lagou.niancheng.core.utils;

import com.lagou.niancheng.core.exceptions.LagouMybatisException;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * com.lagou.niancheng.core.utils.ReflectionUtis
 *
 * @author 大犬
 * @date 2020/3/27
 */
public class ReflectionUtil {
    private ReflectionUtil() {
    }

    public static Class getClass(String className) {
        try {
            return Class.forName(className);
        } catch (Exception e) {
            throw new LagouMybatisException("load class failed ", e);
        }
    }

    public static Field tryGetField(Class classType, String fieldName) {
        try {
            return classType.getDeclaredField(fieldName);
        } catch (Exception e) {
            return null;
        }
    }

    public static Field getField(Class classType, String fieldName) {
        try {
            return classType.getDeclaredField(fieldName);
        } catch (Exception e) {
            throw new LagouMybatisException("get class field failed ", e);
        }
    }

    public static Class tryGetClass(String className) {
        try {
            return Class.forName(className);
        } catch (Exception e) {
            return null;
        }
    }

    public static Object getClassInstance(String className) {
        Class aClass = getClass(className);
        return getClassInstance(aClass);
    }

    public static Object getClassInstance(Class classType) {
        try {
            return classType.newInstance();
        } catch (Exception e) {
            throw new LagouMybatisException("class instant failed ", e);
        }
    }

    public static List<Field> getAllFields(Class classType) {
        List<Field> fields = new ArrayList<>();
        recursiveGetFields(classType, fields);
        return fields;
    }

    private static void recursiveGetFields(Class classType, List<Field> fields) {
        Field[] declaredFields = classType.getDeclaredFields();
        if (declaredFields != null) {
            for (Field declaredField : declaredFields) {
                fields.add(declaredField);
            }
        }
        if (classType.getSuperclass() != Object.class) {
            recursiveGetFields(classType.getSuperclass(), fields);
        }
    }
}
